function SAPFeedLogEntry(activityTimestamp, methodName, responseRequired){
    this.activityTimestamp = activityTimestamp;
    this.methodName = methodName;
    this.responesRequired = responseRequired;
    this.responseTimestamp = -1;
    this.responseCode = null;
    this.responseMessage = null;
    
    this.setResponse = function(response){
        this.responseTimestamp = response.timestamp;
        this.responseCode = response.code;
        this.responseMessage = response.message;        
    }

}

function SAPFeed(serverAddress, clientProgram, userID, password){
  
    
    this.connected = false;
    this.loggedIn = false;
    
    this.client = clientProgram;   
    this.activityLog = [];
 
    this.socket = io.connect(serverAddress);
    
    this.socket.on('connect_failed', function(){
       client.onSAPFeedError({code: "E001", message: "Connection Not Established"}); 
    });

    this.socket.on('error', function(){
       client.onSAPFeedError({code: "E002", message: "Exception in Server-Client Communication"}); 
    });

    this.socket.on('connect', function(){
       connected = true; 
       activityLog.push(activityLog.length, new SAPFeedLogEntry((new Date()).getTime(),"connect_confirmation",false));     
       login(userID, password);
    });
    
    this.socket.on('disconnect', function(){
       connected = false;
       activityLog.push(activityLog.length, new SAPFeedLogEntry((new Date()).getTime(),"disconnect_confirmation",false));
    });
    
    this.socket.on('login_success', function(responseReceived){
        var message = responseReceived.message;
        var code = responseReceived.code;
        var activityID = responseReceived.activityID;
        
        activityLog[activityID].setResponse({timestamp: (new Date()).getTime(), message: message, code: code});           
        loggedIn = true;
        client.onSAPFeedLogin();
    });

    this.socket.on('logout_success', function(responseReceived){
        var message = responseReceived.message;
        var code = responseReceived.code;
        var activityID = responseReceived.activityID;
        
        activityLog[activityID].setResponse({timestamp: (new Date()).getTime(), message: message, code: code});          
        socket.disconnect();
        loggedIn = false;
        client.onSAPFeedLogout();
    });

    this.socket.on('publish_success', function(responseReceived){
        var message = responseReceived.message;
        var code = responseReceived.code;
        var activityID = responseReceived.activityID;
        
        activityLog[activityID].setResponse({timestamp: (new Date()).getTime(), message: message, code: code});          
        
        client.onSAPFeedPublish();
    });
    
    this.socket.on('listen_success', function(responseReceived){
        var message = responseReceived.message;
        var code = responseReceived.code;
        var activityID = responseReceived.activityID;
        
        activityLog[activityID].setResponse({timestamp: (new Date()).getTime(), message: message, code: code});          
        
        client.onSAPFeedListen();
    });
    
    this.socket.on('data_transfer', function(responseReceived){
        
        var activityID = activityLog.length;        
        activityLog[activityID] = (new SAPFeedLogEntry((new Date()).getTime(),'data_transfer',false));       
        
        client.onSAPFeedReceive(responseReceived.publisher, responseReceived.dataset, responseReceived.data);
    });

    this.socket.on('login_failure', function(responseReceived){
        var message = responseReceived.message;
        var code = responseReceived.code;
        var activityID = responseReceived.activityID;
        
        activityLog[activityID].setResponse({timestamp: (new Date()).getTime(), message: message, code: code});
        client.onSAPFeedError({code: code, message: message});
    });

    this.socket.on('logout_failure', function(responseReceived){
        var message = responseReceived.message;
        var code = responseReceived.code;
        var activityID = responseReceived.activityID;
        
        activityLog[activityID].setResponse({timestamp: (new Date()).getTime(), message: message, code: code});
        client.onSAPFeedError({code: code, message: message});
    });

    this.socket.on('publish_failure', function(responseReceived){
        var message = responseReceived.message;
        var code = responseReceived.code;
        var activityID = responseReceived.activityID;
        
        activityLog[activityID].setResponse({timestamp: (new Date()).getTime(), message: message, code: code});
        client.onSAPFeedError({code: code, message: message});
    });

    this.socket.on('listen_failure', function(responseReceived){
        var message = responseReceived.message;
        var code = responseReceived.code;
        var activityID = responseReceived.activityID;
        
        activityLog[activityID].setResponse({timestamp: (new Date()).getTime(), message: message, code: code});
        client.onSAPFeedError({code: code, message: message});
    });

    this.login = function(userID, password){      
        var activityID = activityLog.length;        
        activityLog[activityID] = (new SAPFeedLogEntry((new Date()).getTime(),'login',true));
        var message;
        if(!connected){
            message = "Connection Not Established";
            activityLog[activityID].setResponse({timestamp: (new Date()).getTime(), message: message, code:"E001"});
            client.onSAPFeedError({code: "E001", message: message});
        } else if(loggedIn){
            message = "Duplicated Login";
            activityLog[activityID].setResponse({timestamp: (new Date()).getTime(), message: message, code:"E101"});
            client.onSAPFeedError({code: "E101", message: message});            
        } else{       
            socket.emit("login_request", {activityID: activityID, userID: userID, password: password});
        }
    }
 
    this.logout = function(){
        var activityID = activityLog.length;        
        activityLog[activityID] = (new SAPFeedLogEntry((new Date()).getTime(),'logout',true));
        var message;

        if(!connected){
            message = "Connection Not Established";
            activityLog[activityID].setResponse({timestamp: (new Date()).getTime(), message: message, code:"E001"});
            client.onSAPFeedError({code: "E001", message: message});
        } else if(loggedIn){
            socket.emit("logout_request",{activityID: activityID});
        } else{       
            message = "Action without Login";
            activityLog[activityID].setResponse({timestamp: (new Date()).getTime(), message: message, code:"E103"});
            client.onSAPFeedError({code: "E103", message: message});            
        }
    }
    
    this.publish = function(datasetList, data){
        var activityID = activityLog.length;        
        activityLog[activityID] = (new SAPFeedLogEntry((new Date()).getTime(),'publish',true));        
        
        if(connected&&loggedIn){
            socket.emit("publish",{activityID: activityID, datasetList: datasetList, data: data});
        } else if(!connected){
            message = "Connection Not Established";
            activityLog[activityID].setResponse({timestamp: (new Date()).getTime(), message: message, code:"E001"});
            client.onSAPFeedError({code: "E001", message: message});           
        } else{
            message = "Action without Login";
            activityLog[activityID].setResponse({timestamp: (new Date()).getTime(), message: message, code:"E103"});
            client.onSAPFeedError({code: "E103", message: message});               
        }
    }
 
    this.listen = function(datasetList){
        var activityID = activityLog.length;        
        activityLog[activityID] = (new SAPFeedLogEntry((new Date()).getTime(),'publish',true));                
        if(connected&&loggedIn){
            socket.emit("listen",{activityID: activityID, datasetList: datasetList});
        } else if(!connected){
            message = "Connection Not Established";
            activityLog[activityID].setResponse({timestamp: (new Date()).getTime(), message: message, code:"E001"});
            client.onSAPFeedError({code: "E001", message: message});           
        } else{
            message = "Action without Login";
            activityLog[activityID].setResponse({timestamp: (new Date()).getTime(), message: message, code:"E103"});
            client.onSAPFeedError({code: "E103", message: message});               
        }        
    }

    this.getLog = function(){
        return activityLog;
    }

    return this;
}

